package com.weixing.mall.provider.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.weixing.mall.base.constant.DatePattern;
import com.weixing.mall.base.constant.GlobalConstant;
import com.weixing.mall.base.enums.WhetherEnum;
import com.weixing.mall.base.exception.BusinessException;
import com.weixing.mall.base.orm.MPage;
import com.weixing.mall.base.orm.PageUtil;
import com.weixing.mall.base.utils.EnumUtil;
import com.weixing.mall.base.wrapper.Result;
import com.weixing.mall.core.enums.OrderAppTagEnum;
import com.weixing.mall.core.support.auth.AgentAuth;
import com.weixing.mall.core.support.auth.AuthUtil;
import com.weixing.mall.core.utils.CommonUtil;
import com.weixing.mall.provider.api.model.dto.SaleAgentDto;
import com.weixing.mall.provider.api.model.enums.AgentLevelEnum;
import com.weixing.mall.provider.api.model.enums.OrderTypeEnum;
import com.weixing.mall.provider.api.model.vo.AgentRpcVo;
import com.weixing.mall.provider.api.service.AgentServiceRpc;
import com.weixing.mall.provider.manager.AgentManager;
import com.weixing.mall.provider.manager.ProfitManager;
import com.weixing.mall.provider.mapper.AfterSaleMapper;
import com.weixing.mall.provider.mapper.OrderMapper;
import com.weixing.mall.provider.model.domain.Order;
import com.weixing.mall.provider.model.domain.OrderAgent;
import com.weixing.mall.provider.model.enums.*;
import com.weixing.mall.provider.model.query.*;
import com.weixing.mall.provider.model.query.agent.AgentOrderStatisticQuery;
import com.weixing.mall.provider.model.vo.*;
import com.weixing.mall.provider.model.vo.agent.*;
import com.weixing.mall.provider.model.vo.cliam.CanNotCliamVo;
import com.weixing.mall.provider.model.vo.cliam.OrderCliamResultVo;
import com.weixing.mall.provider.service.IAgentOrderService;
import com.weixing.mall.provider.service.IOrderAgentService;
import com.weixing.mall.provider.service.IOrderService;
import com.weixing.mall.provider.util.AgentOrderUtil;
import com.weixing.mall.provider.util.OrderUtil;
import com.weixing.mall.util.CommUtil;
import com.weixing.mall.util.number.NumberPatternEnum;
import com.weixing.mall.util.number.NumberToRmbUtil;
import jodd.util.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 订单模块-订单表 服务实现类
 * </p>
 *
 * @author Small
 * @since 2019-11-20
 */
@Service
public class AgentOrderServiceImpl implements IAgentOrderService {
    @Autowired
    private AgentServiceRpc agentServiceRpc;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private AfterSaleMapper afterSaleMapper;
    @Autowired
    private IOrderAgentService orderAgentService;
    @Autowired
    private ProfitManager profitManager;
    @Autowired
    private AgentManager agentManager;


    /**
     * 方法描述:
     *  TODO V2版本上线后删除
     *
     * @param abid  代理id
     * @param type   订单类型   1全部  2 已提交  3 待审核  4 已审核  5 代理活动  6 秒杀  7 已认领
     * @return 统计结果
     */
    @Deprecated
    @Override
    public Map<String, Object> getFrontAgentOrderStatistics(Long abid, Integer type) {
        // 订单总数+订单总金额
        AgentStatisticQuery query = getAgentStatisticQuery(abid, type);
        StaticVo result = orderMapper.countAndSumAgentOrder(query);

        Map<String, Object> resultMap = Maps.newHashMap();
        resultMap.put("totalCnt", result.getTotalNum());
        resultMap.put("totalSum", NumberToRmbUtil.format(result.getTotalAmount(), NumberPatternEnum.PAT_DEFAULT.getValue()));
        /*
         * 计算需收款合计和上交款合计
         * *只有全部和待审核的时候才去计算需收款和上交款
         * *实际需要计算只是待审核的订单
         * *
         */
        BigDecimal receivable = BigDecimal.ZERO;
        BigDecimal upPayment = BigDecimal.ZERO;
        if (type == 1 || type == 3) {

            UpPayReceiveVo cntResult = orderAgentService.countReceiveAndUpPay(abid, null, null, null);
            receivable = cntResult.getOwnReceive();
            upPayment = cntResult.getOwnUpPay();
        }
        resultMap.put("receivable", NumberToRmbUtil.format(receivable, NumberPatternEnum.PAT_DEFAULT.getValue()));
        resultMap.put("upPayment", NumberToRmbUtil.format(upPayment, NumberPatternEnum.PAT_DEFAULT.getValue()));
        return resultMap;
    }


    @Override
    public AgentSaleStatisticVo getFrontAgentSalesStatistics(Long agentId, String type, AgentStatisticQuery query) {
        StaticVo todayAchi = null;
        StaticVo totalAchi = null;

        String todayTimeFmt = DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN);
        if ("own".equals(type)) {
            // 今日销售
            AgentStatisticQuery tq = new AgentStatisticQuery();
            tq.setIsPay(WhetherEnum.YES);
            tq.setAgentId(agentId);
            tq.setAuditStartTime(todayTimeFmt);
            tq.setAuditEndTime(todayTimeFmt);
            tq.setAuditStatus(OrderAuditStateEnum.KEFU_AUDITING);
            todayAchi = orderMapper.countAndSumAgentOrder(tq);
            // 累计销售
            totalAchi = getOwnAchi(agentId, query);
        } else if ("group".equals(type)) {
            // 今日销售
            AgentStatisticQuery tq = new AgentStatisticQuery();
            tq.setIsPay(WhetherEnum.YES);
            tq.setAgentIdForQueryAll(agentId);
            tq.setAuditStartTime(todayTimeFmt);
            tq.setAuditEndTime(todayTimeFmt);
            tq.setAuditStatus(OrderAuditStateEnum.KEFU_AUDITING);
            todayAchi = orderMapper.countAndSumAgentOrder(tq);
            // 累计销售
            totalAchi = getGroupAchi(agentId, query);
        }
        AgentSaleStatisticVo vo = new AgentSaleStatisticVo();
        vo.setTodayAchi(null == todayAchi ? "0.00" : NumberToRmbUtil.format(todayAchi.getTotalAmount(), NumberPatternEnum.PAT_DEFAULT.getValue()));
        vo.setTodayAchiCnt(null == todayAchi ? 0 : todayAchi.getTotalNum());
        vo.setTotalAchi(null == totalAchi ? "0.00" : NumberToRmbUtil.format(totalAchi.getTotalAmount(), NumberPatternEnum.PAT_DEFAULT.getValue()));
        vo.setTotalAchiCnt(null == totalAchi ? 0 : totalAchi.getTotalNum());
        return vo;
    }

    @Override
    public AgentSaleStatisticVo getFrontAgentSalesStatistics(AgentOrderQuery query) {
        StaticVo todayAchi = null;
        StaticVo totalAchi = null;
        todayAchi = orderMapper.agentAchievement(wrapSaleAchi(query,true));
        // 累计销售
        totalAchi = orderMapper.agentAchievement(wrapSaleAchi(query,false));
        AgentSaleStatisticVo vo = new AgentSaleStatisticVo();
        vo.setTodayAchi(null == todayAchi ? "0.00" : NumberToRmbUtil.format(todayAchi.getTotalAmount(), NumberPatternEnum.PAT_DEFAULT.getValue()));
        vo.setTodayAchiCnt(null == todayAchi ? 0 : todayAchi.getTotalNum());
        vo.setTotalAchi(null == totalAchi ? "0.00" : NumberToRmbUtil.format(totalAchi.getTotalAmount(), NumberPatternEnum.PAT_DEFAULT.getValue()));
        vo.setTotalAchiCnt(null == totalAchi ? 0 : totalAchi.getTotalNum());
        return vo;
    }

    private AgentOrderQuery wrapSaleAchi(AgentOrderQuery query,boolean isToday) {
        AgentOrderQuery tq = new AgentOrderQuery();
        BeanUtils.copyProperties(query, tq);
        if (isToday){
            String todayTimeFmt = DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN);
            tq.setAuditStartTime(todayTimeFmt);
            tq.setAuditEndTime(todayTimeFmt);
        }

        return tq;
    }

    @Override
    public IPage<FrontAgentOrderVo> selectAfterSaleOrderList(MPage page, AfterSaleQuery query) {
        IPage<FrontAgentOrderVo> iPage = afterSaleMapper.selectAfterSaleOrderList(page, query);
        List<FrontAgentOrderVo> records = iPage.getRecords();
        if (CollUtil.isNotEmpty(records)) {
            for (FrontAgentOrderVo vo : records) {
                OrderAgent orderAgent = orderAgentService.findByOrderIdAndAgentId(vo.getOrderId(), vo.getAgentId());
                vo.setProfit(NumberToRmbUtil.format(orderAgent.getAgentProfit(), NumberPatternEnum.PAT_DEFAULT.getValue()));
                if (AfterSalesTypeEnum.RETURN_GOODS.equals(query.getAfterSaleType())) {
                    vo.setRefunder(orderAgent.getReceivor());
                }
            }
        }
        return iPage;
    }


    /**
     * 包装代理订单统计查询条件
     * TODO v2版本上线后删除
     *
     * @param abid  代理商id
     * @param type  订单类型
     * @return 包装后的查询条件
     */
    @Deprecated
    private AgentStatisticQuery getAgentStatisticQuery(Long abid, Integer type) {
        AgentStatisticQuery query = new AgentStatisticQuery();
        query.setIsPay(WhetherEnum.YES);
        // 1全部  2 已提交  3 待审核  4 已审核  5 代理活动  6 秒杀  7 已认领
        switch (type) {
            case 1:
                // 全部订单
                query.setAgentIdForQueryAll(abid);
                break;
            case 2:
                // 个人订单
                query.setAgentIdForQueryAll(abid);
                break;
            case 3:
                // 待审核订单
                query.setAuditDept(AuditDeptEnum.AGENT);
                query.setAuditor(abid);
                List<Integer> states = Lists.newArrayList();
                states.add(OrderStateEnum.HAS_PAY.getValue());
                states.add(OrderStateEnum.AUDITING.getValue());
                query.setOrderStates(states);
                break;
            case 4:
                // 已审核订单
                query.setHasAuditAgentId(abid);
                break;
            case 5:
                // 代理活动订单
                query.setOrderType(OrderTypeEnum.AGENT);
                query.setAgentIdForQueryAll(abid);
                break;
            case 6:
                // 秒杀订单
                query.setOrderType(OrderTypeEnum.SECKILL);
                query.setAgentIdForQueryAll(abid);
                break;
            case 7:
                // 已认领订单
                query.setAgentId(abid);
                query.setIsClaim(OrderIsClaimEnum.HAS_CLAIM);
            default:
                break;
        }
        return query;
    }


    /**
     * 查询代理订单列表
     *
     * @param page  分页
     * @param query 查询参数
     * @param agentId  代理id
     * @return 订单分页数据
     */
    @Override
    public IPage<FrontAgentOrderVo> selectAgentOrderListOfPage(Page page, AgentOrderQuery query, Long agentId) {
        IPage<FrontAgentOrderVo> iPage = orderMapper.selectAgentOrderList(page, query);
        List<FrontAgentOrderVo> records = iPage.getRecords();
        if (CollUtil.isNotEmpty(records)) {
            for (FrontAgentOrderVo vo : records) {
                vo.setOwnOrder(agentId.equals(vo.getAgentId()));
                OrderStateEnum status = vo.getOrderStatus();
                if (agentId.equals(vo.getAgentId())
                        && OrderAuditStateEnum.AGENT_WAIT_AUDIT.getValue().equals(vo.getAuditStatus())
                        && !OrderStateEnum.REJECT.equals(status)) {
                    if (OrderFromEnum.AGENT.equals(vo.getOrderFrom())) {
                        vo.setCanDel(1);
                    }
                    if (!OrderFromEnum.CUSTOMER.equals(vo.getOrderFrom())) {
                        vo.setCanEdit(1);
                    }
                }

                if (StringUtil.isNotBlank(vo.getAgentCliamLine())) {
                    OrderAgent orderAgent = orderAgentService.findByOrderIdAndAgentId(vo.getOrderId(), agentId);
                    if (null != orderAgent) {
                        vo.setNeedPay(NumberToRmbUtil.format(orderAgent.getNeedUppay(), NumberPatternEnum.PAT_DEFAULT.getValue()));
                        vo.setNeedReceive(NumberToRmbUtil.format(orderAgent.getNeedReceive(), NumberPatternEnum.PAT_DEFAULT.getValue()));
                        vo.setProfit(NumberToRmbUtil.format(orderAgent.getAgentProfit(), NumberPatternEnum.PAT_DEFAULT.getValue()));
                        vo.setPayer(orderAgent.getPayer());
                        vo.setReceivor(orderAgent.getReceivor());
                    }

                }
                // 校验是否待审核
                if (vo.getAuditorId().longValue() == agentId.longValue()
                        && vo.getAuditDept().intValue() == AuditDeptEnum.AGENT.getValue().intValue()
                        && (status.equals(OrderStateEnum.HAS_PAY) || status.equals(OrderStateEnum.AUDITING))) {
                    vo.setWaitAudit(true);
                }
            }
        }
        return iPage;
    }

    /**
     * 代理APP-需上交金额列表
     * @param page 分页
     * @param query 查询条件
     * @param agentId 代理id
     * @return 订单列表
     */
    @Override
    public IPage<FrontAgentOrderVo> selectUpPayOrderList(Page page, AgentOrderQuery query, Long agentId) {
        IPage<FrontAgentOrderVo> iPage = orderMapper.selectUpPayOrderList(page, query);
        List<FrontAgentOrderVo> records = iPage.getRecords();
        if (CollUtil.isNotEmpty(records)) {
            for (FrontAgentOrderVo vo : records) {
                if (StringUtil.isNotBlank(vo.getAgentCliamLine())) {
                    OrderAgent orderAgent = orderAgentService.findByOrderIdAndAgentId(vo.getOrderId(), agentId);
                    if (null != orderAgent) {
                        vo.setNeedPay(NumberToRmbUtil.format(orderAgent.getNeedUppay(), NumberPatternEnum.PAT_DEFAULT.getValue()));
                        vo.setNeedReceive(NumberToRmbUtil.format(orderAgent.getNeedReceive(), NumberPatternEnum.PAT_DEFAULT.getValue()));
                        vo.setProfit(NumberToRmbUtil.format(orderAgent.getAgentProfit(), NumberPatternEnum.PAT_DEFAULT.getValue()));
                        vo.setPayer(orderAgent.getPayer());
                        vo.setReceivor(orderAgent.getReceivor());
                    }
                }
            }
        }
        return iPage;
    }

    @Override
    public Map<String, Object> selectAgentOrderListPriceTotal(AgentOrderQuery query, Long agentId) {
        return orderMapper.selectAgentOrderListPriceTotal(query);
    }

    /**
     * 认领订单
     *
     * @param orders
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void claimOrder(List<Order> orders) {
        Long agentId = AuthUtil.getMemberExt().getAbid();
        // TODO 记着关闭
//        Long agentId = 55964L;
        Result<AgentRpcVo> agentEditVoResult = agentServiceRpc.selectByAgentId(agentId);
        AgentRpcVo agentVo = agentEditVoResult.getData();
        for (Order order : orders) {
            order.setAgentName(agentVo.getAgentName());
            order.setAgentSn(agentVo.getAgentSn());
            order.setAgentId(agentId);
            order.setAgentCliamLine(agentVo.getAgentTreePath());
            order.setIsCliam(WhetherEnum.YES.getValue());
            order.setCustomerId(agentVo.getCustomerId());
            order.setCustomerName(agentVo.getCustomerName());
            order.setAuditDept(AuditDeptEnum.AGENT.getValue());
            order.setAuditor(agentId);
            // 订单所属经销商
            OrderUtil.doOrderAgentClaim(order);
            // 订单所属经销商
            if (null != order.getDistributorId() && 0 != order.getDistributorId()) {
                List<AgentRpcVo> treeList = agentVo.getTreeList();
                int size = treeList.size();
                AgentRpcVo agentRpcVo1 = treeList.get(size - 1);
                if (AgentLevelEnum.DEALER.getValue().equals(agentRpcVo1.getAgentLevel())) {
                    order.setDistributorName(agentRpcVo1.getAgentName());
                }
            }
            List<OrderAgent> list = profitManager.calcProfit(order, agentVo, null);
            if (CollUtil.isNotEmpty(list)) {
                orderAgentService.saveBatch(list);
            }
        }
        orderService.updateBatchById(orders);
        // 更新代理交易日期
        agentManager.updateAgentTradeDate(agentVo);
    }

    @Override
    public List<FrontAgentCliamOrderVo> selectFrontAgentOrderCanClaimlist(String orderSns) {
        String[] orderSnArr = orderSns.split(GlobalConstant.symbol.COMMA);
        return orderMapper.selectFrontAgentOrderCanClaimlist(orderSnArr);
    }


    /**
     * 方法描述: 代理商下单列表
     *
     * @param initMpPage
     * @param query
     * @return com.baomidou.mybatisplus.core.metadata.IPage
     * @Author Small
     * @Date 2020/3/31 18:26
     */
    @Override
    public IPage<KefuAuditOrderVo> selectAgentPlaceOrderList(Page initMpPage, AgentPlaceOrderQuery query) {
        IPage<KefuAuditOrderVo> ipage = orderMapper.selectAgentPlaceOrderList(initMpPage, query);
        List<KefuAuditOrderVo> records = ipage.getRecords();

        // 非代理自己下单手机号隐藏
        if (CollUtil.isNotEmpty(records)) {
            AgentAuth agentExt = AuthUtil.getAgentExt();
            if (null != agentExt) {
                Long aid = agentExt.getAid();
                for (KefuAuditOrderVo vo : records) {
                    if (aid.longValue() != vo.getAgentId().longValue()) {
                        vo.setContactPhone(CommonUtil.coverMobile(vo.getContactPhone()));
                    }
                }
            }
        }
        return ipage;
    }

    @Override
    public RebateStatisticVo getFrontAgentprofitStatistics(Long agentId, AgentOrderQuery query) {
        // 线上返利
        BigDecimal todayProfit = orderAgentService.todayProfit(agentId);
        BigDecimal totalProfit = orderAgentService.totalProfit(agentId, query.getStartTime(), query.getEndTime());
        RebateStatisticVo vo = new RebateStatisticVo();
        vo.setTodayProfit(NumberToRmbUtil.format(todayProfit, NumberPatternEnum.PAT_DEFAULT.getValue()));
        vo.setTotalProfit(NumberToRmbUtil.format(totalProfit, NumberPatternEnum.PAT_DEFAULT.getValue()));
        return vo;
    }

    @Override
    public AbnormalOrderStatisticVo outOfStockReportStatistics(Long agentId, AgentOrderQuery query0) {
        String todayTimeFmt = DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN);
        AgentOrderQuery queryCp = new AgentOrderQuery();
        BeanUtils.copyProperties(query0, queryCp);
        queryCp.setNosuppllyStartTime(todayTimeFmt);
        queryCp.setNosuppllyEndTime(todayTimeFmt);
        StaticVo todayAchi = orderMapper.agentAchievement(queryCp);
        // 累计断货退货
        // 累计销售
        AgentOrderQuery queryCp1 = new AgentOrderQuery();
        BeanUtils.copyProperties(query0, queryCp1);
        StaticVo totalAchi = orderMapper.agentAchievement(queryCp1);
        AbnormalOrderStatisticVo vo = new AbnormalOrderStatisticVo();
        vo.setTotalAchi(totalAchi.getTotalAmount());
        vo.setTodayAchi(todayAchi.getTotalAmount());
        return vo;
    }

    @Override
    public AbnormalOrderStatisticVo selectExchangeStatistics(Long agentId, AfterSaleQuery query0) {
        Result<AgentRpcVo> agentRpcVoResult = agentServiceRpc.selectByAgentId(agentId);
        if (!agentRpcVoResult.isSuccess()) {
            throw new BusinessException("代理商服务暂时不可用");
        }
        AgentRpcVo agentRpcVo = agentRpcVoResult.getData();
        Map<String, Object> result = Maps.newHashMap();

        String todayTimeFmt = DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN);


        // 今日断货总数
        AfterSaleQuery query = new AfterSaleQuery();
//        query.setAgentId(agentId);
        query.setAfterSaleType(AfterSalesTypeEnum.EXCHANE_GOODS);
        query.setStartTime(todayTimeFmt);
        query.setEndTime(todayTimeFmt);
        query.setOrderType(query0.getOrderType());
        wripeQuery(query, agentRpcVo);
        StaticVo todayAchi = afterSaleMapper.countAndSumAfterSale(query);

        // 累计断货退货
        AfterSaleQuery query1 = new AfterSaleQuery();
        query1.setAgentId(agentId);
        query1.setAfterSaleType(AfterSalesTypeEnum.EXCHANE_GOODS);
        query1.setOrderType(query0.getOrderType());
        query1.setStartTime(query0.getStartTime());
        query1.setEndTime(query0.getEndTime());
        wripeQuery(query1, agentRpcVo);
        StaticVo totalAchi = afterSaleMapper.countAndSumAfterSale(query1);
        // 累计销售
        AbnormalOrderStatisticVo vo = new AbnormalOrderStatisticVo();
        vo.setTodayAchi(todayAchi.getTotalAmount());
        vo.setTotalAchi(totalAchi.getTotalAmount());
        return vo;
    }

    @Override
    public AbnormalOrderStatisticVo selectReturnStatistics(Long agentId, AfterSaleQuery query0) {
        Result<AgentRpcVo> agentRpcVoResult = agentServiceRpc.selectByAgentId(agentId);
        if (!agentRpcVoResult.isSuccess()) {
            throw new BusinessException("代理商服务暂时不可用");
        }
        AgentRpcVo agentRpcVo = agentRpcVoResult.getData();
        String todayTimeFmt = DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN);
        // 今日断货总数
        AfterSaleQuery query = new AfterSaleQuery();
        query.setAfterSaleType(AfterSalesTypeEnum.RETURN_GOODS);
        query.setCheckStartTime(todayTimeFmt);
        query.setCheckEndTime(todayTimeFmt);
        query.setOrderType(query0.getOrderType());
        wripeQuery(query, agentRpcVo);
        StaticVo todayAchi = afterSaleMapper.countAndSumAfterSale(query);

        // 累计断货退货
        AfterSaleQuery query1 = new AfterSaleQuery();
        query1.setCheckStartTime(query0.getCheckStartTime());
        query1.setCheckEndTime(query0.getCheckEndTime());
        query1.setOrderType(query0.getOrderType());
        query1.setAfterSaleType(AfterSalesTypeEnum.RETURN_GOODS);
        wripeQuery(query1, agentRpcVo);
        StaticVo totalAchi = afterSaleMapper.countAndSumAfterSale(query1);
        // 累计销售
        AbnormalOrderStatisticVo vo = new AbnormalOrderStatisticVo();
        vo.setTodayAchi(todayAchi.getTotalAmount());
        vo.setTotalAchi(totalAchi.getTotalAmount());
        return vo;
    }

    @Override
    public AbnormalOrderStatisticVo canceledStatistics(AgentOrderQuery query0) {
        String todayTimeFmt = DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN);
        // 今日取消数量
        AgentOrderQuery queryCp = new AgentOrderQuery();
        BeanUtils.copyProperties(query0, queryCp);
        queryCp.setNosuppllyStartTime(todayTimeFmt);
        queryCp.setNosuppllyEndTime(todayTimeFmt);
        StaticVo todayResult = orderMapper.agentAchievement(queryCp);


        // 累计取消数量
        AgentOrderQuery queryCp1 = new AgentOrderQuery();
        BeanUtils.copyProperties(query0, queryCp1);
        StaticVo totalResult = orderMapper.agentAchievement(queryCp1);

        AbnormalOrderStatisticVo vo = new AbnormalOrderStatisticVo();
        vo.setTodayAchi(todayResult.getTotalAmount());
        vo.setTotalAchi(totalResult.getTotalAmount());
        return vo;
    }

    /**
     * 代理APP 业绩报表
     *
     * @param initMpPage  分页参数
     * @param type  订单类型
     * @param query 查询条件
     * @return 业绩报表
     */
    @Override
    public IPage<SalesAchiVo> achievement(Page initMpPage, OrderTypeEnum type, AgentOrderQuery query) {
        long agentId = AuthUtil.getMemberExt().getAbid();
        SaleAgentDto saleAgentDto = new SaleAgentDto();
        saleAgentDto.setCurrentPage(initMpPage.getCurrent());
        saleAgentDto.setPageSize(initMpPage.getSize());
        saleAgentDto.setAgentId(agentId);
        saleAgentDto.setAgentName(query.getAgentName());
//        Result<MPage<AgentRpcVo>> result = agentServiceRpc.selectChildByAgentId(initMpPage.getCurrent(), initMpPage.getSize(), agentId);
        Result<MPage<AgentRpcVo>> result = agentServiceRpc.selectChildByAgent(saleAgentDto);
        if (!result.isSuccess()) {
            throw new BusinessException("代理商服务不可用");
        }
        IPage<AgentRpcVo> iPage = result.getData();
        ArrayList<SalesAchiVo> objects = Lists.newArrayList();

        if (null != iPage) {
            List<AgentRpcVo> records = iPage.getRecords();
            if (CollUtil.isNotEmpty(records)) {
                SalesAchiVo achiVo = null;
                for (AgentRpcVo agentVo : records) {
                    // 销售数量
                    StaticVo salesMap = cntSalesOrder(type.getValue(), query, agentVo);
                    long salesCnt = (long) salesMap.getTotalNum();
                    BigDecimal salesSum = salesMap.getTotalAmount();
//                    // 断货数量
                    StaticVo outOfStockMap = cntOutOfStockOrder(type.getValue(), query, agentVo);
                    long outOfStockCnt = (long) outOfStockMap.getTotalNum();
                    BigDecimal outOfStockSum = outOfStockMap.getTotalAmount();
                    // 取消数量
                    StaticVo cancelMap = cntCancelOrder(type.getValue(), query, agentVo);
                    long cancelCnt = (long) cancelMap.getTotalNum();
                    BigDecimal cancelSum = cancelMap.getTotalAmount();
                    // 退货数量
                    StaticVo returnMap = cntReturnOrder(type.getValue(), query, agentVo);
                    long returnCnt = (long) returnMap.getTotalNum();
                    BigDecimal returnSum = returnMap.getTotalAmount();
                    // 实际销售数量
                    long realCnt = salesCnt - cancelCnt - returnCnt;
                    BigDecimal realSum = NumberUtil.sub(salesSum, cancelSum, returnSum);
                    // 退货比
                    String returnRate = 0 == salesCnt ? "0.00%" : NumberUtil.formatPercent(NumberUtil.div(returnCnt, salesCnt, 2), 2);
                    achiVo = new SalesAchiVo();
                    achiVo.setName(agentVo.getAgentName());
                    achiVo.setSalesCnt(salesCnt);
                    achiVo.setSalesSum(NumberToRmbUtil.defaultFormat(salesSum));
                    achiVo.setOutOfStockCnt(outOfStockCnt);
                    achiVo.setOutOfStockSum(NumberToRmbUtil.defaultFormat(outOfStockSum));
                    achiVo.setCancelCnt(cancelCnt);
                    achiVo.setCancelSum(NumberToRmbUtil.defaultFormat(cancelSum));
                    achiVo.setReturnCnt(returnCnt);
                    achiVo.setReturnSum(NumberToRmbUtil.defaultFormat(returnSum));
                    achiVo.setRealCnt(realCnt);
                    achiVo.setRealSum(NumberToRmbUtil.defaultFormat(realSum));
                    achiVo.setReturnRate(returnRate);
                    objects.add(achiVo);
                }
            }
        }
        MPage mPage = PageUtil.newPage(initMpPage.getCurrent(), initMpPage.getSize(), iPage.getTotal(), objects);
        return mPage;
    }

    @Override
    public StaticVo cntSalesOrder(int orderType, AgentOrderQuery query) {
        query.setOrderType(EnumUtil.getIEnum(OrderTypeEnum.class, orderType));
        return orderMapper.agentAchievement(query);
    }


    private StaticVo cntSalesOrder(int orderType, AgentOrderQuery query, AgentRpcVo agentVo) {
        AgentOrderQuery queryCp = new AgentOrderQuery();
        BeanUtils.copyProperties(query, queryCp);
        queryCp.setOrderType(EnumUtil.getIEnum(OrderTypeEnum.class, orderType));
        queryCp.setAuditStartTime(query.getStartTime());
        queryCp.setAuditEndTime(query.getEndTime());
        queryCp.setStartTime(null);
        queryCp.setEndTime(null);
        wripeQuery(queryCp, agentVo);

        return orderMapper.agentAchievement(queryCp);
    }


    private void wripeQuery(AfterSaleQuery query, AgentRpcVo agentVo) {
        Integer level = agentVo.getAgentLevel();
        query.setDealerId(null);
        query.setLevel1st(null);
        query.setLevel2nd(null);
        query.setLevel3rd(null);
        switch (level) {
            case 1:
                query.setDealerId(agentVo.getId());
                break;
            case 2:
                query.setLevel1st(agentVo.getId());
                break;
            case 3:
                query.setLevel2nd(agentVo.getId());
                break;
            case 4:
                query.setLevel3rd(agentVo.getId());
            default:
                break;
        }
    }

    private void wripeQuery(AgentOrderQuery query, AgentRpcVo agentVo) {
        Integer level = agentVo.getAgentLevel();
        query.setDealerId(null);
        query.setLevel1st(null);
        query.setLevel2nd(null);
        query.setLevel3rd(null);
        switch (level) {
            case 1:
                query.setDealerId(agentVo.getId());
                break;
            case 2:
                query.setLevel1st(agentVo.getId());
                break;
            case 3:
                query.setLevel2nd(agentVo.getId());
                break;
            case 4:
                query.setLevel3rd(agentVo.getId());
            default:
                break;
        }
    }

    @Override
    public StaticVo cntOutOfStockOrder(int orderType, AgentOrderQuery query) {
        query.setOrderType(EnumUtil.getIEnum(OrderTypeEnum.class, orderType));
        query.setItemStatus(ProductStatusEnum.STATUS6.getValue());
        return orderMapper.agentAchievement(query);
    }


    private StaticVo cntOutOfStockOrder(int orderType, AgentOrderQuery query, AgentRpcVo agentRpcVo) {
        AgentOrderQuery queryCp = new AgentOrderQuery();
        BeanUtils.copyProperties(query, queryCp);
        queryCp.setOrderType(EnumUtil.getIEnum(OrderTypeEnum.class, orderType));
        queryCp.setItemStatus(ProductStatusEnum.STATUS6.getValue());
        queryCp.setNosuppllyStartTime(query.getStartTime());
        queryCp.setNosuppllyEndTime(query.getEndTime());
        queryCp.setStartTime(null);
        queryCp.setEndTime(null);
        wripeQuery(queryCp, agentRpcVo);

        return orderMapper.agentAchievement(queryCp);
    }

    @Override
    public StaticVo cntCancelOrder(int orderType, AgentOrderQuery query) {
        query.setOrderType(EnumUtil.getIEnum(OrderTypeEnum.class, orderType));
        query.setOrderStatus(OrderStateEnum.CANCELD);
        return orderMapper.agentAchievement(query);
    }


    private StaticVo cntCancelOrder(int orderType, AgentOrderQuery query, AgentRpcVo agentRpcVo) {

        AgentOrderQuery queryCp = new AgentOrderQuery();
        BeanUtils.copyProperties(query, queryCp);
        queryCp.setOrderType(EnumUtil.getIEnum(OrderTypeEnum.class, orderType));
        queryCp.setItemStatus(ProductStatusEnum.STATUS7.getValue());
        queryCp.setNosuppllyStartTime(query.getStartTime());
        queryCp.setNosuppllyEndTime(query.getEndTime());
        queryCp.setStartTime(null);
        queryCp.setEndTime(null);
        wripeQuery(queryCp, agentRpcVo);

        return orderMapper.agentAchievement(queryCp);
    }

    @Override
    public StaticVo cntReturnOrder(int orderType, AgentOrderQuery query) {
        AfterSaleQuery qs = new AfterSaleQuery();
        qs.setAgentId(query.getAgentId());
        qs.setAfterSaleType(AfterSalesTypeEnum.RETURN_GOODS);
        qs.setOrderType(query.getOrderType());
        qs.setStartTime(query.getStartTime());
        qs.setEndTime(query.getEndTime());
        StaticVo todayAchi = afterSaleMapper.countAndSumAfterSale(qs);
        return todayAchi;
    }


    private StaticVo cntReturnOrder(int orderType, AgentOrderQuery query, AgentRpcVo agentRpcVo) {
        AfterSaleQuery qs = new AfterSaleQuery();
        qs.setAgentId(query.getAgentId());
        qs.setAfterSaleType(AfterSalesTypeEnum.RETURN_GOODS);
        qs.setOrderType(query.getOrderType());
        qs.setCheckStartTime(query.getStartTime());
        qs.setCheckEndTime(query.getEndTime());
        wripeQuery(qs, agentRpcVo);
        StaticVo todayAchi = afterSaleMapper.countAndSumAfterSale(qs);
        return todayAchi;
    }


    @Override
    public FrontAgentOrderDetilsVo selectFrontAgentOrderDetils(Long orderId, Long agentId) {
        FrontAgentOrderDetilsVo faodv = orderMapper.selectFrontAgentOrderDetils(orderId);
        if (faodv != null) {
            faodv.setIsOwn(agentId.equals(faodv.getAgentId()) ? WhetherEnum.YES.getValue() : WhetherEnum.NO.getValue());
            faodv.setIsOnline(OrderFromEnum.MEMBER.equals(faodv.getOrderFrom()) ? WhetherEnum.YES : WhetherEnum.NO);
            faodv.setOrderAppTag(null == faodv.getAppTag() ? "" : EnumUtil.getDesp(OrderAppTagEnum.class, faodv.getAppTag()));
            Result<AgentRpcVo> agentEditVoResult = agentServiceRpc.selectByAgentId(faodv.getParentId());
            if (agentEditVoResult.getData() != null) {
                faodv.setParentName(agentEditVoResult.getData().getAgentName());
            }

            OrderAgent orderAgent = orderAgentService.findByOrderIdAndAgentId(orderId, agentId);
            if (null != orderAgent) {
                faodv.setNeedPay(NumberToRmbUtil.format(orderAgent.getNeedUppay(), NumberPatternEnum.PAT_DEFAULT.getValue()));
                faodv.setNeedReceive(NumberToRmbUtil.format(orderAgent.getNeedReceive(), NumberPatternEnum.PAT_DEFAULT.getValue()));
                faodv.setProfit(NumberToRmbUtil.format(orderAgent.getAgentProfit(), NumberPatternEnum.PAT_DEFAULT.getValue()));
                faodv.setPayer(orderAgent.getPayer());
                faodv.setReceivor(orderAgent.getReceivor());
            }

            if (!agentId.equals(faodv.getAgentId())) {
                //隐藏手机号
                if (StrUtil.isNotEmpty(faodv.getMobile())) {
                    faodv.setMobile(CommUtil.coverMobile(faodv.getMobile()));
                }
                if (StrUtil.isNotEmpty(faodv.getContactPhone())) {
                    faodv.setContactPhone(CommUtil.coverMobile(faodv.getContactPhone()));
                }
            }
        }
        return faodv;
    }

    @Override
    public IPage<KefuAuditOrderVo> selectAuditHisList(Long aid, AgentAuditHisQuery query, Page initMpPage) {
        IPage<KefuAuditOrderVo> pageList = orderMapper.agentAuditHis(initMpPage, query);
        //查询结果不为空
        List<KefuAuditOrderVo> records = pageList.getRecords();
        if (CollUtil.isNotEmpty(records)) {

            //循环set需要的值
            for (KefuAuditOrderVo orderVo : records) {
                if (aid.longValue() != orderVo.getAgentId().longValue()) {
                    orderVo.setContactPhone(CommonUtil.coverMobile(orderVo.getContactPhone()));
                }
                orderVo.setIsBind(StringUtil.isBlank(orderVo.getAgentCliamLine()) ? WhetherEnum.NO : WhetherEnum.YES);
                orderVo.setIsOnline(OrderFromEnum.MEMBER.equals(orderVo.getOrderFrom()) ? WhetherEnum.YES : WhetherEnum.NO);
                orderVo.setOrderSysTag(null == orderVo.getSysTag() ? "" : orderVo.getSysTag().getDesp());
                // 判断是否可删除
                if (OrderFromEnum.AGENT.equals(orderVo.getOrderFrom())
                        && OrderTypeEnum.NORMAL.equals(orderVo.getOrderType())
                        && OrderAuditStateEnum.AGENT_WAIT_AUDIT.equals(orderVo.getAuditStatus())) {
                    orderVo.setCanDel(1);
                }
                //操作时间

                //查询代理商 需收款、需上交款、待审核人、已审核人
                if (StringUtil.isNotBlank(orderVo.getAgentCliamLine())) {

                    String orderAuditorList = orderVo.getOrderAuditorList();
                    if (StringUtil.isNotBlank(orderAuditorList)) {
                        String[] split = orderAuditorList.split(",");
                        int length = split.length;
                        long unauditId = Long.parseLong(split[length - 1]);
                        Result<AgentRpcVo> rpcVoResult = agentServiceRpc.selectByAgentId(unauditId);
                        String auditeName = rpcVoResult.isSuccess() && rpcVoResult.getData() != null ? rpcVoResult.getData().getAgentName() : "";
                        orderVo.setAuditedName(auditeName);
                    }
                    if (AuditDeptEnum.AGENT.equals(orderVo.getAuditDept())) {
                        Result<AgentRpcVo> rpcResult = agentServiceRpc.selectByAgentId(orderVo.getAuditorId());
                        String unauditeName = rpcResult.isSuccess() && rpcResult.getData() != null ? rpcResult.getData().getAgentName() : "";
                        orderVo.setUnAuditor(unauditeName);
                    }

                    if (StringUtil.isNotBlank(orderVo.getAgentCliamLine())) {
                        QueryWrapper<OrderAgent> wrapper = new QueryWrapper<OrderAgent>().eq("order_id", orderVo.getId())
                                .eq("receivor_role", GlobalConstant.RECEIVORROLE_KEFU).eq("role_type", 2);
                        OrderAgent orderAgent = orderAgentService.getOne(wrapper);
                        if (null != orderAgent) {
                            orderVo.setPayAgentName(orderAgent.getAgentName());
                            orderVo.setPayPrice(orderAgent.getNeedUppay());
                        }
                    }
                }
            }
        }
        return pageList;
    }

    @Override
    public AuditHisCntVo auditHisListSta(AgentAuditHisQuery query) {
        return orderMapper.auditHisListSta(query);
    }

    /**
     * 根据订单识别码查询可认领订单
     *
     * @param orderSns 订单识别码，多个识别码用英文逗号隔开
     * @return 可认领详情
     */
    @Override
    public OrderCliamResultVo selectOrderCanClaimlist(String orderSns) {
        String[] orderSnArr = orderSns.split(GlobalConstant.symbol.COMMA);
        if (orderSnArr.length > 100) {
            throw new BusinessException("订单认领条目最大不超过100条");
        }
        List<Order> orderList = orderMapper.selectCliamOrderlistByIdedCodes(orderSnArr);
        // 数组长度
        int arrLen = orderSnArr.length;
        OrderCliamResultVo cliamResultVo = new OrderCliamResultVo();
        /**
         * 1、如果查询结果为空说明订单识别码在数据库中无一命中，订单识别码全部有问题，直接处理失败逻辑
         * 2、如果不为空则进一步判断
         *    2.1、如果数组长度和列表长度一直，代表订单识别码在数据库中全部命中
         *      2.1.1、循环列表，过滤出可认领的订单和不可认领订单，包装返回
         *    2.2、如果数组长度和列表长度不一致，代表部分识别码在数据库中未命中，即部分识别码有问题
         *      2.2.1、循环列表，过滤出可认领的订单和不可认领订单，包装返回
         *      2.2.2、对比数组和列表，过滤出未命中数据库的识别码，存入不可认领订单，包装返回
         */
        if (CollUtil.isNotEmpty(orderList)) {
            int size = orderList.size();
            CanNotCliamVo notCliamVo = null;
            List<CanNotCliamVo> canNotCliamList = Lists.newArrayList();
            List<Order> canCliamList = Lists.newArrayList();
            for (int i = 0; i < size; i++) {
                Order vo = orderList.get(i);
                // 未支付订单不能够认领
                if (WhetherEnum.NO.getValue().equals(vo.getIsPay())) {
                    notCliamVo = new CanNotCliamVo(orderSnArr[i], "订单未支付");
                    canNotCliamList.add(notCliamVo);
                } else if (WhetherEnum.YES.getValue().equals(vo.getIsCliam())) {
                    // 已认领订单不能够认领
                    notCliamVo = new CanNotCliamVo(orderSnArr[i], "订单已被认领");
                    canNotCliamList.add(notCliamVo);
                } else if (0 != vo.getAgentId().longValue()) {
                    // 已绑定代理的订单不能够认领
                    notCliamVo = new CanNotCliamVo(orderSnArr[i], "订单已绑定代理");
                    canNotCliamList.add(notCliamVo);
                } else {
                    // 订单可以认领
                    canCliamList.add(vo);
                }
                // 如果列表长度小于数组长度，则超过部分全为未命中数据库的识别码
                if (i == size - 1 && i < arrLen - 1) {
                    for (int j = i + 1; j < arrLen; j++) {
                        notCliamVo = new CanNotCliamVo(orderSnArr[j], "订单识别码不存在");
                        canNotCliamList.add(notCliamVo);
                    }
                }
            }
            cliamResultVo.setCanNotCliamList(canNotCliamList);
            cliamResultVo.setSuccessCnt(canCliamList.size());
            cliamResultVo.setFailCnt(canNotCliamList.size());
            // 执行认领逻辑
            if (CollUtil.isNotEmpty(canCliamList)) {
                claimOrder(canCliamList);
            }
        } else {
            CanNotCliamVo notCliamVo = null;
            List<CanNotCliamVo> canNotCliamList = Lists.newArrayList();
            for (String sn : orderSnArr) {
                notCliamVo = new CanNotCliamVo(sn, "订单识别码不存在");
                canNotCliamList.add(notCliamVo);
            }
            cliamResultVo.setCanNotCliamList(canNotCliamList);
            cliamResultVo.setFailCnt(canNotCliamList.size());
        }
        return cliamResultVo;
    }

    /**
     * 代理商订单统计
     *
     * @param qs 查询条件
     * @return 统计结果
     */
    @Override
    public AgentOrderStatisticVo orderStatistics(AgentOrderStatisticQuery qs) {
        Long agentId = AuthUtil.getMemberExt().getAbid();
        // 订单总数+订单总金额
        AgentStatisticQuery query = AgentOrderUtil.wrapStatisticQuery(agentId, qs);
        StaticVo result = orderMapper.countAndSumAgentOrder(query);

        AgentOrderStatisticVo statisticVo = new AgentOrderStatisticVo();
        statisticVo.setTotalCnt(result.getTotalNum());
        statisticVo.setTotalSum(NumberToRmbUtil.format(result.getTotalAmount(), NumberPatternEnum.PAT_DEFAULT.getValue()));
        /*
         * 计算需收款合计和上交款合计
         * *只有全部和待审核的时候才去计算需收款和上交款
         * *实际需要计算只是待审核的订单
         * *
         */
        BigDecimal receivable = BigDecimal.ZERO;
        BigDecimal upPayment = BigDecimal.ZERO;
        int type = qs.getType();
        if (type == 1 || type == 3) {

            UpPayReceiveVo cntResult = orderAgentService.countReceiveAndUpPay(agentId, null, null, null);
            receivable = cntResult.getOwnReceive();
            upPayment = cntResult.getOwnUpPay();
        }
        statisticVo.setReceivable(NumberToRmbUtil.format(receivable, NumberPatternEnum.PAT_DEFAULT.getValue()));
        statisticVo.setUpPayment(NumberToRmbUtil.format(upPayment, NumberPatternEnum.PAT_DEFAULT.getValue()));
        return statisticVo;
    }

    private StaticVo getOwnAchi(Long agentId, AgentStatisticQuery query) {
        query.setIsPay(WhetherEnum.YES);
        query.setAgentId(agentId);
        query.setAuditStatus(OrderAuditStateEnum.KEFU_AUDITING);
        return orderMapper.countAndSumAgentOrder(query);
    }

    private StaticVo getGroupAchi(Long agentId, AgentStatisticQuery queryG) {
        queryG.setIsPay(WhetherEnum.YES);
        queryG.setAgentIdForQueryAll(agentId);
        queryG.setAuditStatus(OrderAuditStateEnum.KEFU_AUDITING);
        return orderMapper.countAndSumAgentOrder(queryG);
    }
}
